Input-Output 多路复用

‌‌‌‌  IO 多路复用是使用 select 或 epoll、poll 同时箭筒多个 IO 事件,通过将多个 IO 请求交给内核进行监听。和 同步非阻塞 Input-Output 类似多路复用 IO 也需要轮询。负责 selec 状态查询的线程需要不断的对 select 进行轮询,当查出 select 下有 IO 操作就绪时进行 IO 操作,将数据从内核缓冲区复制到用户缓冲区

IO 多路复用流程

‌‌‌‌  image.png

  1. 选择器注册。先将需要 read 操作的目标文件描述符(socket 连接)提前注册在选择器中,在 about_Java 中式 Selector 类。然后开启 IO 多路复用的轮询流程
  2. 就绪状态的轮询。通过选择器查询所有注册过的文件描述符的 IO 就绪状态。通过查询的系统调用,内核会返回一个就绪的 socket 列表。任何一个 socket 准备好了就代表内核缓存区有数据了。
  3. 用户线程获得就绪的 socket 列表后,根据其中的 socket 连接发起 read 调用,用户线程阻塞。内核将数据从内核缓冲区中复制到用户缓冲区。
  4. 复制完成后,内核返回结果,用户线程才会解除阻塞的状态,用户线程读取到了数据,继续执行

IO 多路复用的优点

  1. 可以同时处理多个 IO 事件,从而提高程序的并发性
  2. 一个线程可以处理多个 IO 事件,减少了系统调用和线程切换和维护的开销,提高了系统性能

IO 多路复用的缺点

‌‌‌‌  本质上 select、epoll 系统效用还是阻塞的,属于同步 IO。需要在读写事件就绪后由系统调用本身负责读写,也就是说读写过程依然是阻塞的。要彻底的解除线程的阻塞,就必须使用 异步 Input-Output